#include "NeoCalendarMask.h"
#include <QPainter>
#include <QParallelAnimationGroup>
#include <QPropertyAnimation>

NeoCalendarMask::NeoCalendarMask(QWidget *parent, bool isAnimationFinishedHide)
    : QWidget(parent),
      pViewOpacity(0.0),
      pZoomRatio(0.0),
      mIsZoomIn(true),
      mOpacityAnimation(new QPropertyAnimation(this, "pViewOpacity", this)),
      mZoomAnimation(new QPropertyAnimation(this, "pZoomRatio", this)),
      mParallelAnimationGroup(new QParallelAnimationGroup(this)),
      mAnimationFinishedCallback(nullptr)
{
    const int duration = 300;

    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);

    mOpacityAnimation->setDuration(duration);
    mOpacityAnimation->setEasingCurve(QEasingCurve::InOutQuad);
    mOpacityAnimation->setStartValue(0);
    mOpacityAnimation->setEndValue(1.0);
    mZoomAnimation->setDuration(duration);
    mZoomAnimation->setEasingCurve(QEasingCurve::InOutQuad);
    mZoomAnimation->setStartValue(0);
    mZoomAnimation->setEndValue(0.15);
    mParallelAnimationGroup->addAnimation(mOpacityAnimation);
    mParallelAnimationGroup->addAnimation(mZoomAnimation);

    connect(mZoomAnimation, &QPropertyAnimation::valueChanged, this, [this](const QVariant &value)
            { this->update(); });
    connect(mParallelAnimationGroup, &QParallelAnimationGroup::finished, this, [this, isAnimationFinishedHide]()
            {
        if (isAnimationFinishedHide) {
            this->hide();
        } 
        if (mAnimationFinishedCallback) {
            mAnimationFinishedCallback();
        } });
}

NeoCalendarMask::~NeoCalendarMask() = default;

void NeoCalendarMask::setStartPixmap(const QPixmap &pixmap)
{
    mStartPixmap = pixmap;
}

void NeoCalendarMask::setEndPixmap(const QPixmap &pixmap)
{
    mEndPixmap = pixmap;
}

void NeoCalendarMask::startAnimation(bool isZoomIn)
{
    mIsZoomIn = isZoomIn;
    mParallelAnimationGroup->start();
}

void NeoCalendarMask::setAnimationFinishedCallback(const QFunction<void()> &callback)
{
    mAnimationFinishedCallback = callback;
}

void NeoCalendarMask::paintEvent(QPaintEvent *event)
{
    NEO_PAINTER_RESET
    const qreal zoomEndValue = mZoomAnimation->endValue().toDouble();

    painter.save();
    painter.setOpacity(1 - pViewOpacity);
    painter.translate(this->rect().center());
    painter.scale(1 + (mIsZoomIn ? pZoomRatio : -pZoomRatio), 1 + (mIsZoomIn ? pZoomRatio : -pZoomRatio));
    painter.translate(-this->rect().center());
    painter.drawPixmap(this->rect(), mStartPixmap);
    painter.restore();
    painter.save();
    painter.setOpacity(pViewOpacity);
    painter.translate(this->rect().center());
    painter.scale(1 + (mIsZoomIn ? pZoomRatio - zoomEndValue : zoomEndValue - pZoomRatio), 1 + (mIsZoomIn ? pZoomRatio - zoomEndValue : zoomEndValue - pZoomRatio));
    painter.translate(-this->rect().center());
    painter.drawPixmap(this->rect(), mEndPixmap);
    painter.restore();
}